3 追蹤者

建立表單

基於 ActiveRecord 的表單:ActiveForm

在 Yii 中使用表單的主要方式是透過 yii\widgets\ActiveForm。當表單基於模型時,應優先選擇此方法。此外,yii\helpers\Html 中有一些有用的方法,通常用於為任何表單新增按鈕和輔助文字。

在客戶端顯示的表單,在大多數情況下都會有一個對應的模型,用於在伺服器端驗證其輸入(有關驗證的更多詳細資訊,請查看驗證輸入章節)。當建立基於模型的表單時,第一步是定義模型本身。該模型可以基於 Active Record 類別(代表來自資料庫的一些資料),或者通用的 Model 類別(從 yii\base\Model 擴展而來)來捕獲任意輸入,例如登入表單。

提示:如果表單欄位與資料庫欄位不同,或者存在僅適用於該表單的格式設定和邏輯,則最好建立一個從 yii\base\Model 擴展而來的獨立模型。

在以下範例中,我們展示了如何將通用模型用於登入表單

<?php

class LoginForm extends \yii\base\Model
{
    public $username;
    public $password;

    public function rules()
    {
        return [
            // define validation rules here
        ];
    }
}

在控制器中,我們將把該模型的實例傳遞給視圖,其中 ActiveForm 小部件用於顯示表單

<?php
use yii\helpers\Html;
use yii\widgets\ActiveForm;

$form = ActiveForm::begin([
    'id' => 'login-form',
    'options' => ['class' => 'form-horizontal'],
]) ?>
    <?= $form->field($model, 'username') ?>
    <?= $form->field($model, 'password')->passwordInput() ?>

    <div class="form-group">
        <div class="col-lg-offset-1 col-lg-11">
            <?= Html::submitButton('Login', ['class' => 'btn btn-primary']) ?>
        </div>
    </div>
<?php ActiveForm::end() ?>

使用 begin()end() 包裝

在上面的程式碼中,ActiveForm::begin() 不僅建立了一個表單實例,還標記了表單的開始。放置在 ActiveForm::begin()ActiveForm::end() 之間的所有內容都將被包裹在 HTML <form> 標籤中。與任何小部件一樣,您可以透過將陣列傳遞給 begin 方法來指定一些選項,以設定小部件的組態。在本例中,傳遞了一個額外的 CSS 類別和識別 ID,用於開頭的 <form> 標籤。對於所有可用的選項,請參閱 yii\widgets\ActiveForm 的 API 文件。

ActiveField

為了在表單中建立表單元素,以及元素的標籤和任何適用的 JavaScript 驗證,呼叫了 ActiveForm::field() 方法,該方法返回 yii\widgets\ActiveField 的實例。當直接回顯此方法的結果時,結果是一個常規(文字)輸入。若要自訂輸出,您可以將 ActiveField 的其他方法鏈接到此呼叫

// a password input
<?= $form->field($model, 'password')->passwordInput() ?>
// adding a hint and a customized label
<?= $form->field($model, 'username')->textInput()->hint('Please enter your name')->label('Name') ?>
// creating a HTML5 email input element
<?= $form->field($model, 'email')->input('email') ?>

這將根據表單欄位定義的 樣板 建立所有 <label><input> 和其他標籤。輸入欄位的名稱是根據模型的 表單名稱 和屬性名稱自動確定的。例如,上述範例中 username 屬性的輸入欄位名稱將為 LoginForm[username]。此命名規則將導致伺服器端 $_POST['LoginForm'] 中提供登入表單的所有屬性陣列。

提示:如果表單中只有一個模型,並且想要簡化輸入名稱,您可以透過覆寫模型的 formName() 方法以返回空字串來跳過陣列部分。這對於 GridView 中使用的篩選器模型以建立更友好的 URL 很有用。

指定模型的屬性可以透過更複雜的方式完成。例如,當屬性在上傳多個檔案或選擇多個項目時可以採用陣列值時,您可以透過在屬性名稱後附加 [] 來指定它

// allow multiple files to be uploaded:
echo $form->field($model, 'uploadFile[]')->fileInput(['multiple'=>'multiple']);

// allow multiple items to be checked:
echo $form->field($model, 'items[]')->checkboxList(['a' => 'Item A', 'b' => 'Item B', 'c' => 'Item C']);

在命名表單元素(例如送出按鈕)時要小心。根據 jQuery 文件,有些保留名稱可能會導致衝突

表單及其子元素不應使用與表單屬性(例如 submitlengthmethod)衝突的輸入名稱或 ID。名稱衝突可能會導致令人困惑的失敗。有關規則的完整列表以及檢查您的標記是否存在這些問題,請參閱 DOMLint

可以使用純 HTML 或使用 Html 輔助工具類別中的方法將其他 HTML 標籤新增到表單中,就像上面的範例中使用 Html::submitButton() 所做的那樣。

提示:如果您在應用程式中使用 Twitter Bootstrap CSS,您可能想要使用 yii\bootstrap\ActiveForm 而不是 yii\widgets\ActiveForm。前者從後者擴展而來,並在產生表單輸入欄位時使用 Bootstrap 特定的樣式。

提示:為了使用星號設定必填欄位的樣式,您可以使用以下 CSS

div.required label.control-label:after {
    content: " *";
    color: red;
}

建立清單

有 3 種清單類型

  • 下拉式選單
  • 單選清單
  • 複選清單

若要建立清單,您必須準備項目。這可以手動完成

$items = [
    1 => 'item 1', 
    2 => 'item 2'
]

或從資料庫檢索

$items = Category::find()
        ->select(['label'])
        ->indexBy('id')
        ->column();

這些 $items 必須由不同的清單小部件處理。表單欄位的值(和當前活動項目)將由 $model 屬性的當前值自動設定。

建立下拉式選單

我們可以使用 ActiveField yii\widgets\ActiveField::dropDownList() 方法來建立下拉式選單

/* @var $form yii\widgets\ActiveForm */

echo $form->field($model, 'category')->dropdownList([
        1 => 'item 1', 
        2 => 'item 2'
    ],
    ['prompt'=>'Select Category']
);

建立單選清單

我們可以使用 ActiveField yii\widgets\ActiveField::radioList() 方法來建立單選清單

/* @var $form yii\widgets\ActiveForm */

echo $form->field($model, 'category')->radioList([
    1 => 'radio 1', 
    2 => 'radio 2'
]);

建立複選清單

我們可以使用 ActiveField yii\widgets\ActiveField::checkboxList() 方法來建立複選清單

/* @var $form yii\widgets\ActiveForm */

echo $form->field($model, 'category')->checkboxList([
    1 => 'checkbox 1', 
    2 => 'checkbox 2'
]);

使用 Pjax

Pjax 小部件允許您更新頁面的特定部分,而不是重新載入整個頁面。您可以使用它僅更新表單並在提交後替換其內容。

您可以設定 $formSelector 以指定哪些表單提交可能會觸發 pjax。如果未設定,則 Pjax 封閉內容內的所有具有 data-pjax 屬性的表單都將觸發 pjax 請求。

use yii\widgets\Pjax;
use yii\widgets\ActiveForm;

Pjax::begin([
    // Pjax options
]);
    $form = ActiveForm::begin([
        'options' => ['data' => ['pjax' => true]],
        // more ActiveForm options
    ]);

        // ActiveForm content

    ActiveForm::end();
Pjax::end();

提示:請小心 Pjax 小部件內的連結,因為回應也將在小部件內呈現。為了避免這種情況,請使用 data-pjax="0" HTML 屬性。

送出按鈕和檔案上傳中的值

在使用 jQuery.serializeArray() 處理 檔案送出按鈕值 時,存在已知問題,這些問題將不會解決,而是被 HTML5 中引入的 FormData 類別取代。

這表示使用 ajax 或使用 Pjax 小部件對檔案和送出按鈕值的唯一官方支援取決於 FormData 類別的 瀏覽器支援

延伸閱讀

下一節 驗證輸入 處理在伺服器端驗證提交的表單資料,以及 ajax 和客戶端驗證。

若要閱讀有關表單更複雜的用法,您可能需要查看以下章節

發現錯字或您認為此頁面需要改進?
在 github 上編輯 !